import axios from "@/axios";
import {assignDeep, getByPath, isEmpty, setByPath} from "@/utils/common";
import {nextTick, reactive, ref} from "vue";
import * as echarts from "echarts";
import {VxeUI} from "@majinju/vxe-pc-ui";
import {ElMessage, ElMessageBox} from "element-plus";
import {options} from "@/plugins/vxe-table";

/**
 * 查询表格方法封装
 */
class SelectGridUtil {
    /**
     * 参数对象
     */
    private _myData:any=reactive<Object>({
        /**
         * 全局统一配置
         */
        options: options,
        tcckShow: false,
        tcckProps:{
            width:"80%",
            height:"80%"
        },
        showEdit: false,
        editTitle: "",
        //操作的行
        obj: null,
        editMode: null,
        /**
         * 对象基础信息
         */
        dxjcxx: {
            sjdx: {
                // dxdm:"",
                cscx:"1"
            },
            sys:{}
        },
        /**
         * 表格基础属性
         */
        gridOptions: {
            /**
             * 列表数据
             */
            data: [],
            /**
             * 分页配置
             */
            pagerConfig: {
                pageSize: options.pager.pageSize,
                pageSizes: options.pager.pageSizes,
                currentPage: 1,
                total: null
            },
        },
        selectReqData: {
            sys: {
                cllx: 'select'
            },
            page: {
                pageNumber: '',
                totalRequired: true,
                pageSize: options.pager.pageSize,
                orderBy: ''
            },
            yobj: {}
        },
        formData: {
        },
        formRule: {
            // xmmc: [{ required: true, message: "请输入名称" }],
        }
    });
    /**
     * 输入参数对象
     */
    private _props:any = {};
    /**
     * 表格引用
     */
    private _xGrid=ref();
    /**
     * 图表引用
     */
    private _echartsRef=ref();
    /**
     * 音频引用
     */
    private _audio=ref();
    /**
     * 配置弹窗引用
     */
    private _xUpdate=ref();

    /**
     * 设置页大小
     * @param pageSize 页大小
     */
    setPageSize(pageSize: any){
        this._myData.selectReqData.page.pageSize = pageSize;
        this._myData.gridOptions.pagerConfig.pageSize = pageSize
    }
    /**
     * 设置当前页
     * @param currentPage 页大小
     */
    setPageNumber(currentPage: any){
        this._myData.selectReqData.page.pageNumber = currentPage;
        this._myData.gridOptions.pagerConfig.currentPage = currentPage
    }
    /**
     * 分页切换事件
     * @param currentPage 当前页
     * @param pageSize 页大小
     */
    pageChange({ currentPage, pageSize }: any){
        this.setPageSize(pageSize);
        this.setPageNumber(currentPage);
        this._myData.selectReqData.page.totalRequired = false
        this.getList();
    }
    /**
     * 自定义字段排序
     * @param column
     */
    sortChange({ column }: any){
        let zddm = getByPath(column, "params.yszddm");
        if(isEmpty(zddm)){
            zddm = column.field

        }
        this._myData.selectReqData.page.orderBy = column.order ? (zddm + " " + column.order) : "";
        this._myData.selectReqData.page.totalRequired = false
        this.getList();
    }
    /**
     * 搜索按钮
     */
    search(){
        let fytjxs = getByPath(this._myData,"dxjcxx.sjdx.fytjxs")
        this._myData.fytjxs = isEmpty(fytjxs)?"1":fytjxs;
        //点击搜索按钮，恢复为第一页
        this.setPageNumber(1);
        this._myData.selectReqData.page.totalRequired = true
        this.getList()
    }
    /**
     * 获取总数
     */
    getTotal(){
        let query = { ...this._myData.selectReqData }
        query.page.totalRequired = true
        query.page.listRequired = false
        axios.post(query).then(req => {
            if (req.data.totalRow >= 0) {
                this._myData.gridOptions.pagerConfig.total = req.data.totalRow;
                this._myData.fytjxs = "0"
            }
        })
    }
    /**
     * 执行分页查询
     */
    getList(isLoading = true){
        this._myData.selectReqData.yobj = this._myData.formData;
        this._myData.selectReqData.page.listRequired = true;
        if (this._myData.fytjxs !== "1") {
            this._myData.selectReqData.page.totalRequired = false;
        }
        if (this._props.getList) {
            this._props.getList(this.getListMr, this._myData, this._xGrid)
        } else {
            this.getListMr(isLoading)
        }
    }
    getListMr(isLoading = true){
        axios.post(this._myData.selectReqData, { tloading: isLoading }).then(req => {
            if ((this._myData.selectReqData.page.totalRequired || this._myData.gridOptions.pagerConfig.total === null)
                && req.data.totalRow >= 0) {
                this._myData.gridOptions.pagerConfig.total = req.data.totalRow;
            }
            if (this._myData.fytjxs === "2" || this._myData.fytjxs === "3") {
                this._myData.gridOptions.pagerConfig.total = 9999999999999999999999;
            }
            this._myData.gridOptions.data = req.data.list
            if (!isEmpty(this._myData.lbmsValue)) {
                this.lbmsChange({ value: this._myData.lbmsValue })
            }
            this.updateEcharts(req.data.list)
            this._xGrid.value.reloadData(this.myData.gridOptions.data)
            if (this.myData.bjsy && !isEmpty(this.myData.bjsy) && this._myData.audioPlay
                && this.myData.gridOptions.data.length > 0) {
                this._audio.value.play();
            }
        }).catch((e) => {
            console.log("查询失败：" + e);
        })
        if (this._myData.fytjxs === "2") {
            this.getTotal()
        }
    }
    lbmsChange({ value }: any){
        this._myData.lbmsValue = value
        if (value !== 'list') {
            this._myData.tableHideClass = "hidden"
            this._myData.lbmsList.map((item: any) => {
                if (item.dm === value) {
                    let option = JSON.parse(JSON.stringify(item.option))
                    option.dataset.source = this._myData.gridOptions.data
                    nextTick(() => {
                        this.updateEcharts(option)
                    })
                    return
                }
            })
        } else {
            this._myData.tableHideClass = ""
        }
    }
    updateEcharts(option: any){
        if(this._myData.tableHideClass !== "hidden"){
            return
        }
        this._myData.echarts = echarts.init(this._echartsRef.value)
        this._myData.echarts.clear()
        this._myData.echarts.setOption(option)
    }

    /**
     * 序号配置
     */
    seqMethod({ rowIndex }: any) {
        return this._myData.gridOptions.pagerConfig.pageSize *
            (this._myData.gridOptions.pagerConfig.currentPage - 1) + rowIndex + 1;
    }
    /**
     * 后台请求
     */
    htqq(params:any){
        return axios.post(assignDeep({
            sjdx:this._myData.dxjcxx.sjdx,
            sys:{
                authCode: this._myData.dxjcxx.sys.authCode,
            }
        },params));
    }

    /**
     * 获取主键字段
     */
    getZjzd(){
        return getByPath(this,"_myData.dxjcxx.sjdx.zddmZjzd")||"id"

    }
    plsc(row?: any){
        const cr = this._xGrid.value.getCheckboxRecords(true);
        if (cr.length === 0&& row === undefined && !this._myData.czqbsj) {
            //没有选中行，且没有要求不选择记录，且不是操作具体某行记录,且没有操作全部数据
            ElMessage.warning("请选择要操作的数据");
            return;
        }
        ElMessageBox.confirm("你确定删除吗?", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning"
        }).then(async () => {
            let ids: any[] = []
            cr.forEach((item: any) => {
                ids.push(item[this.getZjzd()]);
            });
            if (row) {
                ids = [row[this.getZjzd()]];
            }
            await this.htqq({
                sys:{
                    cllx:"plsc",
                    ids:ids
                }
            }).then((response: any) => {
                ElMessage.success(response.msg)
                this.getList()
            })
        }).catch(function () {
            console.info("用户取消操作：删除" )
        })
    }
    /**
     * 导出模板
     */
    dcmb(){
        axios.download({
            sjdx:this._myData.dxjcxx.sjdx,
            sys:{
                authCode: this._myData.dxjcxx.sys.authCode,
                cllx:"dcmb"
            }
        });
    }
    /**
     * 导出模板
     */
    dcdqysj(){
        axios.download({
            sjdx:this._myData.dxjcxx.sjdx,
            sys:{
                authCode: this._myData.dxjcxx.sys.authCode,
                cllx:"dcdqysj"
            },
            yobj:this._myData.selectReqData.yobj,
            page:this._myData.selectReqData.page
        });
    }
    /**
     * 导出模板
     */
    dcsj(){
        axios.download({
            sjdx:this._myData.dxjcxx.sjdx,
            sys:{
                authCode: this._myData.dxjcxx.sys.authCode,
                cllx:"dcsj"
            },
            yobj:this._myData.selectReqData.yobj,
            page: {
                pageSize:5000
            }
        });
    }

    /**
     * 数据批量上传
     */
    async sjplsc(){
        //调用文件上传接口后，再拿着返回的文件对象信息请求设置的处理类型。
        const { files } = await VxeUI.readFile({
            multiple: true
        })
        //后台请求参数,默认
        let htqqcs = {
            "sys.authCode": "QTQX",
            "sys.cllx": "upload",
            // "yobj.sjzt": "default"
        }
        const formBody = new FormData();
        for (const key in htqqcs) {
            formBody.append(key, htqqcs[key]);
        }
        for (let i = 0; i < files.length; i++) {
            formBody.append("files", files[i]);
        }
        axios.upload(formBody).then((res: any) => {
            if (res.status) {
                this.htqq({
                    sys: {
                        cllx:"sjplsc",
                        files: res.data,
                    },
                }).then((response: any) => {
                    ElMessage.info({
                        message: response.msg ? response.msg : "操作成功",
                        showClose: true,
                        duration: 10000
                    })
                    this.getList()
                }).catch(error => {
                    if (error.code === 1001) {
                        axios.post({
                            sjdx: {
                                "dxdm": "SYS_LOG_SJSCCW"
                            },
                            sys: {
                                "cllx": "dxjcxx"
                            }
                        }).then(async res0 => {
                            setByPath(this._myData,"tcckProps.title","数据上传错误列表")
                            this._myData.tcckShow = true
                            await nextTick()
                            await nextTick()
                            res0.data.sys.cllx = 'select'
                            res0.data.fields.qqid.cxmrz = error.qqid
                            await this._xUpdate.value.initPage(res0.data);
                        })
                    }
                });
            }
        });
    }
    editOpen(title:string, editMode:string, row:any){
        this._myData.editTitle = title
        this._myData.editMode = editMode;
        this._myData.obj = row;
        this._myData.showEdit = true;
    };
    editClose(flush=false){
        this._myData.showEdit = false;
        if(flush){
            this.search();
        }
    }
    updateClose(){
        this._myData.tcckShow = false;
    }
    validateFullMsg(errMap:any){
        const msgList: string[] = []
        Object.values(errMap).forEach((errList: any) => {
            errList.forEach((params: any) => {
                const { rowIndex, column, rules } = params
                rules.forEach((rule: any) => {
                    msgList.push(`第 ${rowIndex + 1} 行 ${column.title} 校验错误：${rule.message}`)
                })
            })
        })
        VxeUI.modal.message({
            status: 'error',
            slots: {
                default () {
                    return (
                        <div class="red" style="max-height: 400px;overflow: auto;">
                        {
                            msgList.map(msg => <div>{ msg }</div>)
                        }
                        </div>
                )
                }
            }
        })
        return;
    }
    footerMethod(){
        let data = this._myData.gridOptions.data;
        const fields = this._myData.dxjcxx.fields;
        let hj = {}
        for (const key in fields) {
            const f = fields[key];
            let jshj = getByPath(f.kzxxObj, "cllxkz.select.jshj");
            if (typeof jshj === "number") {
                //根据配置计算合计
                hj[key] = data.reduce((acc: any, cur: any) => {
                    return acc + cur[key]
                }, 0).toFixed(jshj)
            }else if(jshj){
                hj[key] = jshj
            }
        }
        return [ hj ]
    }
    constructor(myData: any) {
        assignDeep(this._myData,myData);
        assignDeep(this._myData,{
            selectReqData: {
                sjdx: this._myData.dxjcxx.sjdx,
                sys: {
                    authCode: this._myData.dxjcxx.sys.authCode,
                }
            }
        });
        //初始化查询
        if (this._myData.dxjcxx.sjdx.cscx === '1') {
            this.search();
        }
    }

    get myData(): any {
        return this._myData;
    }

    set myData(value: any) {
        this._myData = value;
    }

    get xGrid(): any {
        return this._xGrid;
    }

    set xGrid(value: any) {
        this._xGrid = value;
    }

    get props(): any {
        return this._props;
    }

    set props(value: any) {
        this._props = value;
    }

    get echartsRef(): any {
        return this._echartsRef;
    }

    set echartsRef(value: any) {
        this._echartsRef = value;
    }

    get audio(): any {
        return this._audio;
    }

    set audio(value: any) {
        this._audio = value;
    }

    get xUpdate(): any {
        return this._xUpdate;
    }

    set xUpdate(value: any) {
        this._xUpdate = value;
    }
}
export default SelectGridUtil;